# -*- coding: utf-8 -*-#
__author__ = 'yangq'
import random

from tornado import gen
from appcommon.appinstance import mysql_app_pool
from common import timetool
from random import Random, uniform
import hashlib


def get_share_score_random():
    return float('%.2f' % uniform(0, 0.2))


def create_md5(str):
    m = hashlib.md5()
    m.update(str)
    return m.hexdigest()


@gen.coroutine
def update_user_info(flag, openid, nick_name, avatar, current_time, device_type, platform_type, from_code):
    param = u"nick_name='{}', avatar='{}',".format(nick_name, avatar) if flag else ""
    sql = (
        u"update app_user_info set {} modify_time={}, "
        u" device_type={},platform_type='{}',from_code='{}' where openid = '{}'"
    )
    yield mysql_app_pool.get_one(sql.format(
       param, current_time, device_type, platform_type, from_code, openid
    ))
    res = True
    raise gen.Return(res)


@gen.coroutine
def add_user_info(flag, phone, openid, nick_name, avatar, platform_type, current_time, device_type, from_code):
    phone_code = create_md5(phone)
    sql = (
        "insert into app_user_info (flag, phone, openid, nick_name, avatar, platform_type, create_time, device_type, phone_code, from_code) values "
        u"({}, '{}', '{}', '{}', '{}', {}, {}, {}, '{}', '{}')"
    )
    yield mysql_app_pool.insert_one(sql.format(flag, phone, openid, nick_name, avatar, platform_type, current_time, device_type, phone_code, from_code))
    res = True
    raise gen.Return(res)


@gen.coroutine
def del_user_info_with_phone(phone):
    try:
        sql = (
            "delete from app_user_info where phone='{}'"
        )
        yield mysql_app_pool.delete(sql.format(phone))
        res = True
    except Exception, e:
        print e
        res = False
    raise gen.Return(res)


@gen.coroutine
def save_sign_log(phone, device_type, client_id, current_time, version, device_token):
    try:
        sql = (
            "insert into app_sign_log (phone, device_type, client_id, sign_time, version, device_token) values "
            u"('{}', {}, '{}', {}, '{}', '{}')"
        )
        yield mysql_app_pool.insert_one(sql.format(
            phone, device_type, client_id, current_time, version, device_token
        ))
        res = True
    except Exception, e:
        print e
        res = False
    raise gen.Return(res)


@gen.coroutine
def update_client_id(phone, device_type, client_id, current_time, device_token):
    if phone:
        sql1 = "select id from app_clientids where phone = '{}'"
        phone_exist = yield mysql_app_pool.get_one(sql1.format(phone), cursor='dict')
        if phone_exist:
            sql2 = "update app_clientids set phone='' where id = '{}'"
            yield mysql_app_pool.delete(sql2.format(phone_exist['id']))


    sql = "select 1 from app_clientids where device_token = '{}'"
    info = yield mysql_app_pool.get_one(sql.format(device_token), cursor='dict')
    if info:
        sql_update = (
            "update app_clientids set device_type={}, phone='{}',client_id='{}', pubtime={}"
            " where device_token='{}'")
        yield mysql_app_pool.update(sql_update.format(
            device_type, phone, client_id, current_time, device_token
        ))
    else:
        sql_insert = (
            "insert into app_clientids (device_type,device_token, phone, client_id, pubtime) "
            "values ({}, '{}', '{}', '{}', {})"
        )
        yield mysql_app_pool.update(sql_insert.format(
            device_type, device_token, phone, client_id, current_time
        ))

    raise gen.Return({})


@gen.coroutine
def get_userinfo_with_phone(phone):
    sql = (
        u"select phone, nick_name, avatar, flag, phone_code from app_user_info  where phone = '{}'"
    )
    res = yield mysql_app_pool.get_one(sql.format(phone), cursor='dict')
    raise gen.Return(res)


@gen.coroutine
def get_userinfo_with_openid(openid):
    sql = (
        u"select phone, nick_name, avatar, flag, phone_code from app_user_info  where openid = '{}'"
    )
    res = yield mysql_app_pool.get_one(sql.format(openid), cursor='dict')

    raise gen.Return(res)


@gen.coroutine
def update_login_info(phone, device_type, current_time, from_code):
    try:
        sql = (
            u"update app_user_info set modify_time={}, device_type={}, from_code = '{}' where phone = '{}'"
        )
        yield mysql_app_pool.update(sql.format(current_time, device_type, from_code, phone))
        res = True
    except Exception, e:
        print e
        res = False
    raise gen.Return(res)


@gen.coroutine
def update_user_area(phone, area):
    sql = (
        u"update app_user_info set area = '{}' where phone = '{}'"
    )
    yield mysql_app_pool.update(sql.format(area, phone))
    raise gen.Return(1)


@gen.coroutine
def check_phone_is_vip1(phone, current_time=0):
    if not current_time:
        current_time = timetool.get_timestamp()
    if phone:
        sql = (
            u"select 1 from app_vip_user where phone='{}' and start < {} and end > {}"
        )
        vip = yield mysql_app_pool.get_one(sql.format(phone, current_time, current_time))
        res = "1" if vip else "0"
    else:
        res = "0"
    raise gen.Return(res)


@gen.coroutine
def check_phone_is_vip4(phone, current_time=0):
    if not current_time:
        current_time = timetool.get_timestamp()
    if phone:
        sql = (
            u"select 1 from app_vip4_user where phone='{}' and start < {} and end > {}"
        )
        vip = yield mysql_app_pool.get_one(sql.format(phone, current_time, current_time))
        res = "1" if vip else "0"
    else:
        res = "0"
    raise gen.Return(res)


@gen.coroutine
def check_phone_is_vip(phone, current_time=0):
    if not current_time:
        current_time = timetool.get_timestamp()
    is_vip1 = yield check_phone_is_vip1(phone, current_time)
    if is_vip1 == '1':
        res = "1"
    else:
        is_vip4 = yield check_phone_is_vip4(phone, current_time)
        if is_vip4 == '1':
            res = '1'
        else:
            res = "0"
    raise gen.Return(res)


@gen.coroutine
def check_phone_is_couch(phone):
    res = "0"
    if phone:
        sql = (
            u"select status from couch_auth where phone='{}'"
        )
        is_couch = yield mysql_app_pool.get_one(sql.format(phone))
        if is_couch:
            if is_couch[0] == 1:
                res = "1"
    raise gen.Return(res)


@gen.coroutine
def update_avatar_nick(phone, nick_name, avatar, current_time):
    param = u", avatar='{}'".format(avatar[0]) if avatar else ""
    sql = (
        u"update app_user_info set nick_name = '{}' {}, flag=0, modify_time={} where phone='{}'"
    )
    yield mysql_app_pool.update(sql.format(nick_name, param, current_time, phone))
    user_info = yield get_userinfo_with_phone(phone)
    res = user_info['avatar'] if user_info else ""
    raise gen.Return(res)


@gen.coroutine
def get_sj_nick_name():
    seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    sa = []
    for i in range(10):
        sa.append(random.choice(seed))
    nick_name = 'sj_'+''.join(sa)
    raise gen.Return(nick_name)


@gen.coroutine
def check_phone_is_silence(phone):
    if phone:
        sql = (
            u"select 1 from app_circle_silence_user where phone='{}'"
        )
        silence = yield mysql_app_pool.get_one(sql.format(phone))
        res = "1" if silence else "0"
    else:
        res = "0"
    raise gen.Return(res)


@gen.coroutine
def check_today_added(phone):
    today = timetool.get_current_date()
    start = timetool.convert_date_to_timestamp(today + ' 00:00:00')
    end = timetool.convert_date_to_timestamp(today + ' 23:59:59')
    if phone:
        sql = (
            u"select 1 from app_score_log where phone='{}' and pubtime >= {} and pubtime <= {} and type=2"
        )
        added = yield mysql_app_pool.get_one(sql.format(phone, start, end))
        res = True if added else False
    else:
        res = True
    raise gen.Return(res)


@gen.coroutine
def update_score_2_mysql(phone, action, score):
    sql = (
        u"select * from app_user_score where phone='{}'"
    )
    old_score = yield mysql_app_pool.get_one(sql.format(phone), cursor='dict')
    if old_score:
        if action == 'add':
            news_score = old_score['score'] + score
        else:
            news_score = old_score['score'] - score
        sql = (
            u"update app_user_score set score = {} where phone='{}' "
        )
        yield mysql_app_pool.update(sql.format(news_score, phone))
    else:
        if action == 'add':
            news_score = score
        else:
            news_score = 0 - score
        sql = (
            u"insert into app_user_score (phone, score) values ('{}', {})"
        )
        yield mysql_app_pool.update(sql.format(phone, news_score))
    raise gen.Return(news_score)


@gen.coroutine
def save_score_log(phone, score, type, pubtime, from_phone=""):
    sql = (
        "insert into app_score_log (phone, score, type, pubtime, from_phone) values "
        "('{}', {}, {}, {}, '{}')"
    )
    yield mysql_app_pool.insert_one(sql.format(phone, score, type, pubtime, from_phone))
    raise gen.Return(0)


@gen.coroutine
def get_score_from_score_conf(user_type, source):
    sql = "select score from app_score_conf where user_type='{}' and source = '{}'"
    info = yield mysql_app_pool.get_one(sql.format(user_type, source), cursor='dict')
    res = info['score']
    raise gen.Return(res)


def create_random_code(random_length=8):
    """
    随机生成8位随机兑换码
    :param random_length:
    :return:
    """
    res = 'QC'
    chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    length = len(chars) - 1
    random = Random()
    for i in range(random_length):
        res += chars[random.randint(0, length)]
    return res


@gen.coroutine
def check_exchange_code_is_ok(ex_code):
    search_sql = (
        "select 1 from app_red where status = 0 and ex_code = '{ex_code}';"
    )
    res = yield mysql_app_pool.get_one(search_sql.format(ex_code=ex_code))
    raise gen.Return(res)


@gen.coroutine
def create_exchange_code():
    not_ok = 1
    while not_ok:
        res = create_random_code()
        not_ok = yield check_exchange_code_is_ok(res)
    raise gen.Return(res)


@gen.coroutine
def save_red_ex_code(phone, money, ex_code, current_time):
    search_sql = (
        "insert into app_red (phone, ex_code, money, status, create_time) values "
        "('{}', '{}', {}, 0, {})"
    )
    res = yield mysql_app_pool.get_one(search_sql.format(phone, ex_code, money, current_time))
    raise gen.Return(res)


@gen.coroutine
def check_scre_enough(phone, money):
    sql = (
        u"select * from app_user_score where phone='{}'"
    )
    old_score = yield mysql_app_pool.get_one(sql.format(phone), cursor='dict')
    if not old_score:
        res = False
    else:
        res = True if old_score['score'] >= money else False
    raise gen.Return(res)


@gen.coroutine
def get_from_phone(phone):
    sql = (
        "select phone from app_user_info where phone_code = ( "
        "select from_code from app_user_info where phone = '{}' "
        ")"
    )
    from_phone = yield mysql_app_pool.get_one(sql.format(phone), cursor='dict')
    res = from_phone['phone'] if from_phone else ""
    raise gen.Return(res)


@gen.coroutine
def get_last_version(device_type):
    sql = (
        "select * from app_version where device_type = {} order by version desc limit 1"

    )
    res = yield mysql_app_pool.get_one(sql.format(device_type), cursor='dict')
    raise gen.Return(res)


@gen.coroutine
def get_score_list(phone, pubtime, page_count):
    param = "and a.pubtime < {}".format(pubtime) if pubtime else ""
    sql = (
        "select a.phone, a.score, a.type, a.desc, a.pubtime, a.from_phone, b.avatar,b.nick_name "
        "from app_score_log a LEFT JOIN app_user_info b ON "
        "a.from_phone = b.phone "
        "where a.phone = '{}' {} order by pubtime desc limit {}"
    )
    res = yield mysql_app_pool.get_all(sql.format(phone, param, page_count), cursor='dict')
    raise gen.Return(res)


@gen.coroutine
def get_user_scre(phone):
    sql = (
        u"select score from app_user_score where phone='{}'"
    )
    score = yield mysql_app_pool.get_one(sql.format(phone), cursor='dict')
    if not score:
        score = {'score': 0}
    raise gen.Return(score)


@gen.coroutine
def get_vip_cnt():
    sql = "select count(*) as cnt from app_vip_user "
    res = yield mysql_app_pool.get_one(sql, cursor='dict')
    raise gen.Return(res['cnt'])


@gen.coroutine
def check_wx_bind(open_id):
    sql = "select phone from wx_bind where open_id = '{}' "
    info = yield mysql_app_pool.get_one(sql.format(open_id), cursor='dict')
    res = info['phone'] if info else ""
    raise gen.Return(res)


@gen.coroutine
def bind_wx_phone(phone, open_id):
    sql1 = "select 1 from wx_bind where phone = '{}'"
    info1 = yield mysql_app_pool.get_one(sql1.format(phone))
    if info1:
        sql = "update wx_bind set open_id = '{}' where phone = '{}'"
        info = yield mysql_app_pool.update(sql.format(open_id, phone))
    else:
        sql = "insert into wx_bind (phone, open_id) values ('{}', '{}')"
        info = yield mysql_app_pool.insert_one(sql.format(phone, open_id))
    raise gen.Return(info)


@gen.coroutine
def get_last_notice_time():
    sql = (
        "select end_time from app_push_task where type = 2 "
        "and status = 2 "
        "order by end_time limit 1"
    )
    info = yield mysql_app_pool.get_one(sql, cursor='dict')
    res = info['end_time'] if info else 0
    raise gen.Return(res)


@gen.coroutine
def get_last_reply_time(phone, couch):
    current_time = timetool.get_timestamp()
    sql = (
        "select end_time from app_push_task where type = 0 "
        "and status = 2 "
        "and info_id in ( "
        "select id from app_circle_reply where to_phone = '{}' "
        "and couch = {} "
        "and create_time > {} ) "
        "order by end_time limit 1"

    )
    info = yield mysql_app_pool.get_one(sql.format(phone, couch, current_time - 60*60*24*90), cursor='dict')
    res = info['end_time'] if info else 0
    raise gen.Return(res)


@gen.coroutine
def get_last_zan_time(phone, couch):
    current_time = timetool.get_timestamp()
    sql = (
        "select end_time from app_push_task where type = 1 "
        "and status = 2 "
        "and info_id in ( "
        "select id from app_circle_zan where to_phone = '{}' "
        "and couch = {} "
        "and pubtime > {} ) "
        "order by end_time limit 1"

    )
    info = yield mysql_app_pool.get_one(sql.format(phone, couch, current_time - 60*60*24*90), cursor='dict')
    res = info['end_time'] if info else 0
    raise gen.Return(res)


@gen.coroutine
def get_last_consult_time(phone):
    current_time = timetool.get_timestamp()
    sql = (
        "select end_time from app_push_task where type = 5 "
        "and status = 2 "
        "and info_id in ( "
        "select id from student_consult where couch_phone = '{}' "
        "and add_time > {} ) "
        "order by end_time limit 1"

    )
    info = yield mysql_app_pool.get_one(sql.format(phone, current_time - 60*60*24*90), cursor='dict')
    res = info['end_time'] if info else 0
    raise gen.Return(res)


@gen.coroutine
def get_base_cnt():
    sql = (
        "select * from app_base_cnt"
    )
    info = yield mysql_app_pool.get_one(sql, cursor='dict')
    raise gen.Return(info)


@gen.coroutine
def check_couch_sign_added(phone):
    today_begin = timetool.get_timestamp_of_before_day(0, 0)
    sql = (
        "select 1 from couch_score_log where phone ='{}' and type='sign' and pubtime > {}"
    )
    info = yield mysql_app_pool.get_one(sql.format(phone, today_begin), cursor='dict')
    raise gen.Return(info)


@gen.coroutine
def check_zhuce_added(from_phone):
    # phone from_phone 调换,奖金日志表设计原因
    sql = (
        "select 1 from app_score_log where from_phone='{}' and `type`= 5"
    )
    info = yield mysql_app_pool.get_one(sql.format(from_phone), cursor='dict')
    raise gen.Return(info)


@gen.coroutine
def add_score_after_zhuce(phone):
    from_phone = yield get_from_phone(phone)
    is_couch = yield check_phone_is_couch(from_phone)
    if is_couch == "1":
        added = yield check_zhuce_added(phone)  # phone from_phone 调换,奖金日志表设计原因
        if not added:
            current_time = timetool.get_timestamp()
            add_score = yield get_score_from_score_conf('couch', 'zhuce')
            yield update_score_2_mysql(from_phone, 'add', add_score)
            yield save_score_log(from_phone, add_score, '5', current_time, phone)
